import { useEffect, useMemo } from "react";
import { styled, createGlobalStyle, css } from "styled-components";

function App() {
  const keys: Record<string, { frequency: number }> = {
    Q: {
      frequency: 261,
    },
    W: {
      frequency: 293,
    },
    E: {
      frequency: 329,
    },
    R: {
      frequency: 349,
    },
    T: {
      frequency: 392,
    },
    Y: {
      frequency: 440,
    },
    U: {
      frequency: 494,
    },
    I: {
      frequency: 523,
    },
    O: {
      frequency: 587,
    },
    P: {
      frequency: 659,
    },
    A: {
      frequency: 698,
    },
    S: {
      frequency: 784,
    },
    D: {
      frequency: 880,
    },
    F: {
      frequency: 988,
    },
    // A: {
    //   frequency: 196,
    // },
    // S: {
    //   frequency: 220,
    // },
    // D: {
    //   frequency: 246,
    // },
    // F: {
    //   frequency: 261,
    // },
    // G: {
    //   frequency: 293,
    // },
    // H: {
    //   frequency: 329,
    // },
    // J: {
    //   frequency: 349,
    // },
    // K: {
    //   frequency: 392,
    // },
  };

  const GlobalStyles = createGlobalStyle`
    body {
      background: #000;
    }
    .pressed {
      background: #aaa;
    }
  `;

  const KeysStyle = styled.div`
    width: 800px;
    height: 400px;
    margin: 40px auto;

    display: flex;
    flex-direction: row;
    justify-content: space-between;
    overflow: hidden;
  `;
  const textStyle = css`
    line-height: 500px;
    text-align: center;
    font-size: 50px;
  `;

  const KeyStyle = styled.div`
    border: 4px solid black;
    background: #fff;
    flex: 1;
    ${textStyle}

    &:hover {
      background: #aaa;
    }
  `;

  const context = useMemo(() => {
    return new AudioContext();
  }, []);

  const play = (key: string) => {
    const frequency = keys[key]?.frequency;
    if (!frequency) {
      return;
    }

    const osc = context.createOscillator();
    osc.type = "sine";
    osc.frequency.value = frequency;

    const gain = context.createGain();
    osc.connect(gain);
    gain.connect(context.destination);

    gain.gain.setValueAtTime(0, context.currentTime);
    gain.gain.linearRampToValueAtTime(1, context.currentTime + 0.01);

    osc.start(context.currentTime);

    gain.gain.exponentialRampToValueAtTime(0.001, context.currentTime + 1);
    osc.stop(context.currentTime + 1);

    document.getElementById(`key-${key}`)?.classList.add("pressed");
    setTimeout(() => {
      document.getElementById(`key-${key}`)?.classList.remove("pressed");
    }, 100);
  };

  useEffect(() => {
    document.addEventListener("keydown", (e) => {
      play(e.key.toUpperCase());
    });
  }, []);

  const map: Record<number, string> = {
    1: "Q",
    2: "W",
    3: "E",
    4: "R",
    5: "T",
    6: "Y",
    7: "U",
    8: "I",
    9: "O",
    10: "P",
    11: "A",
    12: "S",
    13: "D",
    14: "F",
    15: "G",
    16: "H",
    17: "J",
    18: "K",
    19: "L",
    20: "Z",
    21: "X",
    22: "C",
    23: "V",
    24: "B",
    25: "N",
  };

  const playSong1 = () => {
    const music: number[][] = [
      [6, 1000],
      [7, 1200],
      [8, 2000],
      [7, 1200],
      [8, 1500],
      [10, 1600],
      [7, 2000],
      [3, 1000],
      [6, 1500],
      [5, 600],
      [6, 1000],
      [8, 1500],
      [5, 2000],
      [3, 1200],
      [4, 1200],
      [3, 800],
      [4, 800],
      [8, 1400],
      [3, 2000],
      [8, 400],
      [8, 600],
      [7, 2000],
      [7, 600],
      [5, 400],
      [5, 600],
      [7, 600],
      [7, 2000],
    ];

    playMusic(music);
  };

  const palySong2 = () => {
    const music: number[][] = [
      [6, 1000],
      [6, 1000],
      [6, 1000],
      [3, 500],
      [6, 500],
      [5, 1000],
      [3, 500],
      [2, 500],
      [3, 1000],
    ];

    playMusic(music);
  };

  const playSong3 = () => {
    const music: number[][] = [
      [1, 1000],
      [2, 1000],
      [3, 1000],
      [1, 1000],
      [6, 1000],
      [5, 800],
      [6, 800],
      [1, 1000],
      [7, 1000],
      [6, 800],
      [7, 1000],
      [7, 1000],
      [6, 800],
      [7, 1000],
      [3, 1000],
      [8, 500],
      [9, 500],
      [8, 500],
      [7, 500],
      [6, 1000],
      [5, 1000],
      [6, 1000],
      [5, 500],
      [6, 1000],
      [5, 1000],
      [6, 1000],
      [5, 1000],
      [6, 1000],
      [5, 1000],
      [2, 500],
      [5, 1000],
      [3, 1000],
    ];

    playMusic(music);
  };

  function playMusic(music: number[][]) {
    let startTime = 0;
    music.forEach((item) => {
      setTimeout(() => {
        play(map[item[0]]);
      }, startTime * 0.5);
      startTime += item[1];
    });
  }

  return (
    <div>
      <KeysStyle as="section">
        {Object.keys(keys).map((item: any) => {
          return (
            <KeyStyle as="div" key={item}>
              <div onClick={() => play(item)} id={`key-${item}`}>
                <span>{item}</span>
              </div>
            </KeyStyle>
          );
        })}
        <GlobalStyles />
      </KeysStyle>
      <div style={{ display: "flex", width: 200 }}>
        <button onClick={() => playSong1()}>天空之城</button>
        <button onClick={() => palySong2()}>奢香夫人</button>
        <button onClick={() => playSong3()}>起风了</button>
        {/* <button onClick={() => playSong1()}>世上只有妈妈好</button>
        <button onClick={() => playSong2()}>奢香夫人</button> */}
      </div>
    </div>
  );
}

export default App;
